Optional Benchmarking.f

Requires Tools
Requires Seki
Requires Quicksort

{ don't try to pass values directly to benchmark quotations.  use locals instead. }

Only Forth Definitions

: median  ( addr count -- n )
  2dup sort 2/ cells + @ ;

-? 2variable acc

: mean  ( addr count -- n )
  .0 acc 2!
  locals| c |
  c 0 do @+ acc m+! loop drop
  acc 2@ c m/ ;


-? 0 value reps
-? 0 value xt

\ variable use-gl-flush?

\ We use the mean for this because performance can vary widely with the fill rate.
:[] gl-benchmark:[  ( reps xt -- median )
  to xt to reps
  reps cells temp:[
    dup >q
    reps 0 do
      ucounter drop
      xt execute
      glFlush   \ To get a real picture of the fill rate.
      ucounter drop swap - !+
      end-frame
    loop drop
    q> reps mean
  ;] ;

16678 constant 60hz

\ We use the median for this because usually pure Forth code is deterministic, but
\   Windows and modern CPU architecture introduces multitasking and cache influences that causes "blips".
: (benchmark)
  to xt to reps
  reps cells temp:[
    dup >q
    reps 0 do
      ucounter drop
      xt execute
      ucounter drop swap - !+
    loop drop
    q> reps median
  ;] ;

:[] benchmark:[  ( reps xt -- median )
   (benchmark) ;

: benchmark
   200 ' (benchmark) ." took " . ." microseconds." ;

: gltime
  ucounter drop ' execute glFinish ucounter drop swap - ." took " . ." microseconds." ;

: fps   ( microseconds -- fps. )
   1000000 swap ./ ;

: drawtime  ( microseconds -- percent. )
   60hz ./ 100.0 .* ;

: .drawtime   drawtime .. ." %" ;
